// -*- mode: c++ -*-
/* Enclave.edl - Top EDL file. */

enclave {

  include "stdbool.h"
  include "sgx_key_exchange.h"
  include "sgx_trts.h"
  from "sgx_tkey_exchange.edl" import *;

  trusted {
    public void ecall_project(
      [in, count=project_list_length] uint8_t *project_list, size_t project_list_length,
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [out] uint8_t **output_rows, [out] size_t *output_rows_length);

    public void ecall_filter(
      [in, count=condition_length] uint8_t *condition, size_t condition_length,
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [out] uint8_t **output_rows, [out] size_t *output_rows_length);

    public void ecall_encrypt(
      [user_check] uint8_t *plaintext, uint32_t length,
      [user_check] uint8_t *ciphertext, uint32_t cipher_length);

    public void ecall_decrypt(
      [in, size=ciphertext_length] uint8_t *ciphertext, uint32_t ciphertext_length,
      [out, size=plaintext_length] uint8_t *plaintext, uint32_t plaintext_length);

    public void ecall_sample(
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [out] uint8_t **output_rows, [out] size_t *output_rows_length);

    public void ecall_find_range_bounds(
      [in, count=sort_order_length] uint8_t *sort_order, size_t sort_order_length,
      uint32_t num_partitions,
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [out] uint8_t **output_rows, [out] size_t *output_rows_length);

    public void ecall_partition_for_sort(
      [in, count=sort_order_length] uint8_t *sort_order, size_t sort_order_length,
      uint32_t num_partitions,
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [user_check] uint8_t *boundary_rows, size_t boundary_rows_length,
      [out, count=num_partitions] uint8_t **output_partitions,
      [out, count=num_partitions] size_t *output_partition_lengths);

    public void ecall_external_sort(
      [in, count=sort_order_length] uint8_t *sort_order, size_t sort_order_length,
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [out] uint8_t **output_rows, [out] size_t *output_rows_length);

    public void ecall_scan_collect_last_primary(
      [in, count=join_expr_length] uint8_t *join_expr, size_t join_expr_length,
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [out] uint8_t **output_rows, [out] size_t *output_rows_length);

    public void ecall_non_oblivious_sort_merge_join(
      [in, count=join_expr_length] uint8_t *join_expr, size_t join_expr_length,
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [user_check] uint8_t *join_row, size_t join_row_length,
      [out] uint8_t **output_rows, [out] size_t *output_rows_length);

    public void ecall_non_oblivious_aggregate_step1(
      [in, count=agg_op_length] uint8_t *agg_op, size_t agg_op_length,
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [out] uint8_t **first_row, [out] size_t *first_row_length,
      [out] uint8_t **last_group, [out] size_t *last_group_length,
      [out] uint8_t **last_row, [out] size_t *last_row_length);

    public void ecall_non_oblivious_aggregate_step2(
      [in, count=agg_op_length] uint8_t *agg_op, size_t agg_op_length,
      [user_check] uint8_t *input_rows, size_t input_rows_length,
      [user_check] uint8_t *next_partition_first_row, size_t next_partition_first_row_length,
      [user_check] uint8_t *prev_partition_last_group, size_t prev_partition_last_group_length,
      [user_check] uint8_t *prev_partition_last_row, size_t prev_partition_last_row_length,
      [out] uint8_t **output_rows, [out] size_t *output_rows_length);

    public sgx_status_t ecall_enclave_init_ra(int b_pse,
                                              [out] sgx_ra_context_t *p_context);
    public void ecall_enclave_ra_close(sgx_ra_context_t context);
    public sgx_status_t ecall_verify_att_result_mac(sgx_ra_context_t context,
                                                    [in,size=message_size] uint8_t* message,
                                                    size_t message_size,
                                                    [in,size=mac_size] uint8_t* mac,
                                                    size_t mac_size);
    public sgx_status_t ecall_put_secret_data(sgx_ra_context_t context,
                                              [in,size=secret_size] uint8_t* p_secret,
                                              uint32_t secret_size,
                                              [in,count=16] uint8_t* gcm_mac);
  };

  untrusted {
    void ocall_print_string([in, string] const char *str);
    void ocall_malloc(size_t size, [out] uint8_t **ret);
    void ocall_free([user_check] uint8_t *buf);
    void ocall_exit(int exit_code);
  };

};
